package net.zoneland.zrdp.framework.web.service.uniflow.impl;


import net.zoneland.uniflow.client.ApplyTaskPageObject;
import net.zoneland.uniflow.client.NodeObject;
import net.zoneland.uniflow.client.ProcessCurrentObject;
import net.zoneland.uniflow.client.ProcessServiceException;
import net.zoneland.uniflow.client.ReadObject;
import net.zoneland.uniflow.client.ReadPageObject;
import net.zoneland.uniflow.client.ReadQueryParam;
import net.zoneland.uniflow.client.TaskDecisionObject;
import net.zoneland.uniflow.client.TaskObject;
import net.zoneland.uniflow.client.TaskPageObject;
import net.zoneland.uniflow.client.TaskQueryParam;
import net.zoneland.uniflow.client.UserInfo;
import net.zoneland.uniflow.client.impl.SyncProcessServiceClient;
import net.zoneland.uniflow.client.impl.SyncTaskServiceClient;
import net.zoneland.zrdp.common.core.page.Pager;
import net.zoneland.zrdp.common.utils.JacksonUtils;
import net.zoneland.zrdp.framework.config.properties.UniflowProperties;
import net.zoneland.zrdp.framework.web.common.enums.AdditionFlagEnum;
import net.zoneland.zrdp.framework.web.common.enums.TaskStatusEnum;
import net.zoneland.zrdp.framework.web.domain.mapstruct.UniflowConverter;
import net.zoneland.zrdp.framework.web.domain.uniflow.*;
import net.zoneland.zrdp.framework.web.service.uniflow.WorkFlowService;
import net.zoneland.zrdp.common.core.domain.entity.SysUser;
import net.zoneland.zrdp.common.exception.BizException;
import net.zoneland.zrdp.common.utils.SecurityUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 统一流程接口服务.
 *
 * @version v1.0
 */
@Service
@DependsOn("commonHttpClientPoolExecutor")
public class WorkFlowServiceImpl implements WorkFlowService {
    private static final Logger LOGGER = LoggerFactory.getLogger(WorkFlowServiceImpl.class);


    /** 流程决策业务操作: {@value}. 同步调度**/
    private final SyncProcessServiceClient processClient;
    /** 任务调度业务操作: {@value}. 同步调度 **/
    private final SyncTaskServiceClient taskClient;

    /** 流程平台系统配置: {@value}. **/
    private final String systemId;

    /**
     * 构造流程信息初始.
     * @author Pbody
     **/
    @Autowired
    public WorkFlowServiceImpl(@Qualifier("commonHttpClientPoolExecutor") final CloseableHttpClient commonHttpClient, final UniflowProperties uniflowProperties) {
        this.systemId = uniflowProperties.getSystemId();
        final String userName = uniflowProperties.getUserName();
        final String password = uniflowProperties.getPassword();
        //流程接口服务
        processClient = new SyncProcessServiceClient(userName, password);
        processClient.setServerAddress(uniflowProperties.getProcessUrl());
        processClient.setHttpClient(commonHttpClient);
        //任务接口服务
        taskClient = new SyncTaskServiceClient(userName, password);
        taskClient.setServerAddress(uniflowProperties.getTaskUrl());
        taskClient.setHttpClient(commonHttpClient);
    }

    /**
     * 启动流程.
     * @param startProcessParam 流程启动参数对象.
     * @return List<TaskObject> 任务实例集合（处理后可能生成多个任务实例）
     **/
    @Override
    public List<TaskObject> startProcess(final StartProcessParam startProcessParam) {
        try {
            // 申请人为空时，申请人处理人默认当前登录人.
            final UserInfo userInfo = getUserInfo(startProcessParam.getOwner());
            return Arrays.asList(processClient.startProcess(
                startProcessParam.getBusinessProcess(),
                userInfo,
                startProcessParam.getApplyId(),
                startProcessParam.getApplyTitle(),
                startProcessParam.getSubmit(),
                getUserInfos(startProcessParam.getHandlers(), userInfo),
                startProcessParam.getExtendData(),
                startProcessParam.getNextTaskExtData()));
        } catch (final ProcessServiceException ex) {
            LOGGER.error("流程启动出错，startProcessParam：{}", startProcessParam);
            throw new BizException("流程启动出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 复活流程到指定任务（只对已流转结束的流程有效）.
     * @param completeTaskParam 任务处理参数对象.
     * @return List<TaskObject> 任务实例集合（处理后可能生成多个任务实例）
     **/
    @Override
    public List<TaskObject> reliveProcessTasks(final CompleteTaskParam completeTaskParam) {
        try {
            return Arrays.asList(processClient.reliveProcess2Tasks(
                completeTaskParam.getPiid(),
                toArray(completeTaskParam.getTiidList(), new String[0]),
                getUserInfo(completeTaskParam.getOwner()),
                completeTaskParam.getOption(),
                completeTaskParam.getNotion()));
        } catch (final ProcessServiceException ex) {
            LOGGER.error("复活流程到指定任务出错，completeTaskParam：{}", completeTaskParam);
            throw new BizException("复活流程到指定任务出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 删除流程.
     * @author YTG
     * @param piid 流程实例ID.
     * @param applicant 当前处理人信息.
     * @param notion 审批意见.
     * @return Boolean 删除调用是否成功
     **/
    @Override
    public Boolean deleteProcess(final String piid, final UserInfo applicant, final String notion) {
        try {
            processClient.deleteProcess(piid, getUserInfo(applicant), notion);
            return Boolean.TRUE;
        } catch (final ProcessServiceException ex) {
            LOGGER.error("删除流程出错，piid：{}", piid);
            throw new BizException("删除流程出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 任务处理.
     * @author YTG
     * @param completeTaskParam 任务处理参数对象.
     * @return List<TaskObject> 任务实例集合（处理后可能生成多个任务实例）
     **/
    @Override
    public List<TaskObject> completeTask(final CompleteTaskParam completeTaskParam) {
        try {
            // 处理人为空时，申请人处理人默认当前登录人.
            final UserInfo userInfo = getUserInfo(completeTaskParam.getOwner());
            return Arrays.asList(taskClient.completeTask(
                completeTaskParam.getTiid(),
                userInfo,
                completeTaskParam.getDecision(),
                completeTaskParam.getOption(),
                completeTaskParam.getNotion(),
                completeTaskParam.getNextNode(),
                getUserInfos(completeTaskParam.getHandlers(), userInfo),
                completeTaskParam.getExtendData(),
                completeTaskParam.getApplyTitle(),
                completeTaskParam.getNextTaskExtData()));
        } catch (final ProcessServiceException ex) {
            LOGGER.error("任务处理出错，completeTaskParam：{}", completeTaskParam);
            throw new BizException("任务处理出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 流程任务跳转.
     * @author YTG
     * @param completeTaskParam 任务处理参数对象.
     * @return List<TaskObject> 任务实例集合（处理后可能生成多个任务实例）
     **/
    @Override
    public List<TaskObject> nodeJump(final CompleteTaskParam completeTaskParam) {
        try {
            return Arrays.asList(taskClient.nodeJump(
                completeTaskParam.getTiid(),
                completeTaskParam.getNextNode(),
                getUserInfos(completeTaskParam.getHandlers(), getLoginUserInfo()),
                completeTaskParam.getOwner(),
                completeTaskParam.getOption(),
                completeTaskParam.getNotion(),
                completeTaskParam.getExtendData(),
                completeTaskParam.getNextTaskExtData()));
        } catch (final ProcessServiceException ex) {
            LOGGER.error("流程任务跳转出错，completeTaskParam：{}", completeTaskParam);
            throw new BizException("流程任务跳转出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 待办任务跳转.
     * @author YTG
     * @param completeTaskParam 任务处理参数对象.
     * @return List<TaskObject> 任务实例集合（处理后可能生成多个任务实例）
     **/
    @Override
    public List<TaskObject> readyNodeJump(final CompleteTaskParam completeTaskParam) {
        try {
            // 设置查询待办任务参数.
            final TaskQueryParam taskQueryParam = new TaskQueryParam();
            taskQueryParam.setPiid(completeTaskParam.getPiid());
            taskQueryParam.setStates(new int[]{TaskStatusEnum.READY.getValue()});
            taskQueryParam.setExcludeNodes(new String[]{completeTaskParam.getNextNode()});

            // 查询待办任务.
            final TaskObject[] taskObjects = taskClient.queryTasks(taskQueryParam);

            // 遍历待办任务，并跳转.

            return Arrays.stream(taskObjects)
                .map(x -> completeTaskParam.setTiid(x.getTiid()).setSuspendTask(Boolean.TRUE))
                .map(this::nodeJump)
                .flatMap(Collection::stream)
                .collect(Collectors.toList());
        } catch (final ProcessServiceException ex) {
            LOGGER.error("待办任务跳转出错，completeTaskParam：{}", completeTaskParam);
            throw new BizException("待办任务跳转出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 强制任务处理.
     * @author YTG
     * @param completeTaskParam 任务处理参数对象.
     * @return List<TaskObject> 任务实例集合（处理后可能生成多个任务实例）
     **/
    @Override
    public List<TaskObject> forceCompleteTask(final CompleteTaskParam completeTaskParam) {
        try {
            // 处理人为空时，申请人处理人默认当前登录人.
            final UserInfo userInfo = getUserInfo(completeTaskParam.getOwner());
            return Arrays.asList(taskClient.forceCompleteTask(
                completeTaskParam.getTiid(),
                userInfo,
                completeTaskParam.getDecision(),
                completeTaskParam.getOption(),
                completeTaskParam.getNotion(),
                completeTaskParam.getNextNode(),
                getUserInfos(completeTaskParam.getHandlers(), userInfo),
                TaskStatusEnum.READY.getValue(),
                completeTaskParam.getExtendData(),
                completeTaskParam.getApplyTitle(),
                completeTaskParam.getNextTaskExtData()));
        } catch (final ProcessServiceException ex) {
            LOGGER.error("批量处理待办出错，completeTaskParam：{}", completeTaskParam);
            throw new BizException("批量处理待办出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 待办,已办分页任务查询.
     * @author YTG
     * @param param 查询参数.
     * @param page 页数,从1计数.
     * @param pageSize 每页的大小.
     * @return TaskPageObject 任务列表分页数据
     **/
    @Override
    public TaskPageObject queryTasksByPage(final TaskQueryParam param, final int page,
                                                           final int pageSize) {
        try {
            return taskClient.queryTasksByPage(param, page, pageSize);
        } catch (final ProcessServiceException ex) {
            LOGGER.error("待办,已办分页任务查询出错，param：{}", JacksonUtils.toString(param));
            throw new BizException("待办,已办分页任务查询出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 待办,已办分页最新任务查询.
     * @author YTG
     * @param param 查询参数.
     * @param page 页数,从1计数.
     * @param pageSize 每页的大小.
     * @return ApplyTaskPageObject 任务列表分页数据
     **/
    @Override
    public ApplyTaskPageObject queryFinishedApplyTasksByPage(final TaskQueryParam param, final int page, final int pageSize) {
        try {
            return taskClient.queryFinishedApplyTasksByPage(new String[]{systemId}, param, page, pageSize);
        } catch (final ProcessServiceException ex) {
            LOGGER.error("待办,已办分页最新任务查询出错，param：{}", JacksonUtils.toString(param));
            throw new BizException("待办,已办分页最新任务查询出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 查询流程当前信息.
     * @author YTG
     * @param piid 流程编码.
     * @return ProcessCurrentObject 当前流程信息
     **/
    @Override
    public ProcessCurrentObject queryProcessCurrentInfo(final String piid) {
        try {
            return processClient.queryProcessCurrentInfo(piid);
        } catch (final ProcessServiceException ex) {
            LOGGER.error("查询流程当前信息出错，piid：{}", piid);
            throw new BizException("查询流程当前信息出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 修改工单标题.注意需要同步修改数据库中的数据
     * @author YTG
     * @param piid 流程编码.
     * @param applyTitle 工单标题.
     * @return Integer操作结果。0表示成功，其他值（一般不会出现）待定
     **/
    @Override
    public Integer setApplyTitle(final String piid, final String applyTitle) {
        try {
            return processClient.setApplyTitle(piid, applyTitle);
        } catch (final ProcessServiceException ex) {
            LOGGER.error("修改工单标题出错，piid：{}", piid);
            throw new BizException("修改工单标题出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 待办，已办不分页查询.
     * @author YTG
     * @param param 查询参数.
     * @return List<TaskObject> 任务列表
     **/
    @Override
    public List<TaskObject> queryTasks(final TaskQueryParam param) {
        try {
            return Arrays.asList(taskClient.queryTasks(param));
        } catch (final ProcessServiceException ex) {
            LOGGER.error("待办，已办不分页查询出错，param：{}", JacksonUtils.toString(param));
            throw new BizException("待办，已办不分页查询出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 待阅,已阅分页任务查询.
     * @author YTG
     * @param param 查询参数.
     * @param page 页数,从1计数.
     * @param pageSize 每页的大小.
     * @return ReadPageObject 待阅,已阅任务列表分页数据
     **/
    @Override
    public ReadPageObject queryReadsByPage(final ReadQueryParam param, final int page, final int pageSize) {
        try {
            return taskClient.queryReadsByPage(param, page, pageSize);
        } catch (final ProcessServiceException ex) {
            LOGGER.error("待阅,已阅分页任务查询出错，param：{}", JacksonUtils.toString(param));
            throw new BizException("待阅,已阅分页任务查询出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 待阅、已阅不分页任务查询.
     * @author YTG
     * @param param 查询参数.
     * @return List<ReadObject> 任务列表
     **/
    @Override
    public List<ReadObject> queryReads(final ReadQueryParam param) {
        try {
            return Arrays.asList(taskClient.queryReads(param));
        } catch (final ProcessServiceException ex) {
            LOGGER.error("待阅、已阅不分页任务查询出错，param：{}", JacksonUtils.toString(param));
            throw new BizException("待阅、已阅不分页任务查询出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 查询任务下所有决策.
     * @author YTG
     * @param systemId 系统编码.
     * @param businessProcess 流程模板编码.
     * @param node 节点编码.
     * @return List<TaskDecisionObject> 决策列表
     **/
    @Override
    public List<TaskDecisionObject> queryTaskDecisions(final String systemId, final String businessProcess, final String node) {
        try {
            return Arrays.asList(taskClient.queryTaskDecisions(systemId, businessProcess, node));
        } catch (final ProcessServiceException ex) {
            LOGGER.error("查询任务下所有决策出错，businessProcess：{}，node：{}", businessProcess, node);
            throw new BizException("查询任务下所有决策出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 查询运行时任务决策（决策中有判断，只查询判断结果为true）.
     * @author YTG
     * @param piid 流程编号.
     * @param nodeId 节点编码.
     * @param extendData 扩展参数.
     * @return List<TaskDecisionObject> 决策列表
     **/
    @Override
    public List<TaskDecisionObject> queryTaskRuntimeDecisions(final String piid, final String nodeId,
                                                              final Map<String, String> extendData) {
        try{
            return Arrays.asList(taskClient.queryTaskRuntimeDecisions(piid, nodeId, extendData));
        }catch (final ProcessServiceException ex){
            LOGGER.error("查询运行时任务决策出错，piid：{}，nodeId：{}，extendData：{}", piid, nodeId, extendData);
            throw new BizException("查询运行时任务决策出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 任务实例查询.
     * @author YTG
     * @param tiid 任务编码.
     * @return TaskObject 任务实例
     **/
    @Override
    public TaskObject getTask(final String tiid) {
        try {
            return taskClient.getTask(tiid);
        } catch (final ProcessServiceException ex) {
            LOGGER.error("任务实例查询出错，tiid：{}", tiid);
            throw new BizException("任务实例查询出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 流程任务转交.
     * @author YTG
     * @param completeTaskParam 任务处理参数对象.
     * @return List<TaskObject> 任务实例列表
     **/
    @Override
    public List<TaskObject> transferTask(final CompleteTaskParam completeTaskParam) {
        try {
            return Arrays.asList(taskClient.transferTask(
                completeTaskParam.getTiid(),
                getUserInfos(completeTaskParam.getHandlers(), getLoginUserInfo()),
                completeTaskParam.getOption(),
                completeTaskParam.getNotion(),
                completeTaskParam.getApplyTitle()));
        } catch (final ProcessServiceException ex) {
            LOGGER.error("流程任务转交出错，completeTaskParam：{}", completeTaskParam);
            throw new BizException("流程任务转交出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 查询流程模板节点.
     * @author YTG
     * @param businessProcess 流程模板编码.
     * @param priorityVer 流程模板版本号.
     * @param nodeId 节点编号.
     * @return NodeObject 节点信息
     **/
    @Override
    public NodeObject queryProcessTemplateNode(final String businessProcess, final int priorityVer, final String nodeId) {
        try {
            return processClient.queryProcessTemplateNode(businessProcess, priorityVer, nodeId);
        } catch (final ProcessServiceException ex) {
            LOGGER.error("查询流程模板节点出错，businessProcess：{}，nodeId：{}", businessProcess, nodeId);
            throw new BizException("查询流程模板节点出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 查询流程模板节点.
     * @author YTG
     * @param businessProcess 流程模板编码.
     * @param priorityVer 流程模板版本号.
     * @return List<NodeObject> 模版节点列表
     **/
    @Override
    public List<NodeObject> queryProcessTemplateNodes(final String businessProcess, final int priorityVer) {
        try {
            return Arrays.asList(processClient.queryProcessTemplateNodes(businessProcess, priorityVer));
        } catch (final ProcessServiceException ex) {
            LOGGER.error("查询流程模板节点出错，businessProcess：{}", businessProcess);
            throw new BizException("查询流程模板节点出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 查询流程扩展参数.
     * @author YTG
     * @param piid 流程编码.
     * @param paramNames 扩展参数名称.
     * @return Map<String,String> 扩展参数
     **/
    @Override
    public Map<String, String> queryExtendData(final String piid, final String[] paramNames) {
        try {
            return processClient.queryExtendData(piid, paramNames);
        } catch (final ProcessServiceException ex) {
            LOGGER.error("查询流程扩展参数出错，piid：{}，paramNames：{}", piid, paramNames);
            throw new BizException("查询流程扩展参数出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 设置流程扩展参数.
     * @author YTG
     * @param piid 流程编码.
     * @param extendData 扩展参数.
     * @return Integer 操作结果。0表示成功，其他值（一般不会出现）待定
     **/
    @Override
    public Integer setExtendData(final String piid, final Map<String, String> extendData) {
        try {
            return processClient.setExtendData(piid, extendData);
        } catch (final ProcessServiceException ex) {
            LOGGER.error("设置流程扩展参数出错，piid：{}，extendData：{}", piid, extendData);
            throw new BizException("设置流程扩展参数出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 查询任务扩展数据.
     * @author YTG
     * @param tiid 任务编码.
     * @param extendParamNames 扩展参数名称.
     * @return Map<String,String> 扩展参数
     **/
    @Override
    public Map<String, String> queryTaskExtendData(final String tiid, final String[] extendParamNames) {
        try {
            return taskClient.queryTaskExtendData(tiid, extendParamNames);
        } catch (final ProcessServiceException ex) {
            LOGGER.error("查询任务扩展数据出错，tiid：{}，extendParamNames：{}", tiid, extendParamNames);
            throw new BizException("查询任务扩展数据出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 设置任务扩展数据.
     * @author YTG
     * @param tiid 任务编码.
     * @param extendData 扩展参数.
     * @return Integer 操作结果。0表示成功，其他值（一般不会出现）待定
     **/
    @Override
    public Integer setTaskExtendData(final String tiid, final Map<String, String> extendData) {
        try {
            return taskClient.setTaskExtendData(tiid, extendData);
        } catch (final ProcessServiceException ex) {
            LOGGER.error("设置任务扩展数据出错，tiid：{}，extendData：{}", tiid, extendData);
            throw new BizException("设置任务扩展数据出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 创建待阅.
     * @author YTG
     * @param createReadsParam 创建待阅参数对象.
     * @return List<ReadObject> 待阅列表
     **/
    @Override
    public List<ReadObject> createReads(final CreateReadsParam createReadsParam) {
        try {
            // 处理人为空时，申请人处理人默认当前登录人.
            final UserInfo userInfo = getUserInfo(createReadsParam.getOwner());
            return Arrays.asList(taskClient.createReads(
                createReadsParam.getPiid(),
                createReadsParam.getNode(),
                getUserInfos(createReadsParam.getHandlers(), userInfo),
                null, createReadsParam.getApplyTitle(),
                createReadsParam.getExtendData(),
                userInfo,
                AdditionFlagEnum.REPEAT.getValue()));
        } catch (final ProcessServiceException ex) {
            LOGGER.error("创建待阅出错，createReadsParam：{}", createReadsParam);
            throw new BizException("创建待阅出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 获取待阅任务.
     * @author YTG
     * @param riid 任务编码.
     * @return ReadObject 待阅任务
     **/
    @Override
    public ReadObject getRead(final String riid) {
        try {
            return taskClient.getRead(riid);
        } catch (final ProcessServiceException ex) {
            LOGGER.error("获取待阅任务出错，riid：{}", riid);
            throw new BizException("获取待阅任务出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 完成待阅.
     * @author YTG
     * @param riid 任务编码.
     * @param notion 审批意见.
     * @return Integer 操作结果。0表示成功，其他值（一般不会出现）待定
     **/
    @Override
    public Integer completeRead(final String riid, final String notion) {
        try {
            return taskClient.completeRead(riid, notion);
        } catch (final ProcessServiceException ex) {
            LOGGER.error("完成待阅出错，riid：{}", riid);
            throw new BizException("完成待阅出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 查询任务数量.
     * @author YTG
     * @param param 任务查询参数对象.
     * @return Integer 任务数量
     **/
    @Override
    public Integer queryTasksCount(final TaskQueryParam param) {
        try {
            return taskClient.queryTaskCount(param);
        } catch (final ProcessServiceException ex) {
            LOGGER.error("查询任务数量出错，param：{}", param);
            throw new BizException("查询任务数量出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 查询待阅数量.
     * @author YTG
     * @param param 待阅查询参数对象.
     * @return Integer 待阅数量
     **/
    @Override
    public Integer queryReadCount(final ReadQueryParam param) {
        try {
            return taskClient.queryReadCount(param);
        } catch (final ProcessServiceException ex) {
            LOGGER.error("查询待阅数量出错，param：{}", JacksonUtils.toString(param));
            throw new BizException("查询待阅数量出错，异常信息：" + ex.getLocalizedMessage(), ex);
        }
    }

    /**
     * 将任务分页结果转化成Pager格式.
     * @author YTG
     * @param taskPageObject 任务Pager对象.
     * @return Pager<TaskObjectPojo> 任务分页信息
     **/
    @Override
    public Pager<TaskObjectPojo> transformTasksToPager(final TaskPageObject taskPageObject) {
        return UniflowConverter.INSTANCE.transformTasksToPager(taskPageObject);
    }

    /**
     * 将最新任务分页结果转化成Pager格式.
     * @author YTG
     * @param applyTaskPageObject 最新任务Pager对象.
     * @return Pager<TaskObjectPojo> 任务分页信息
     **/
    @Override
    public Pager<TaskObjectPojo> transformTasksToPager(final ApplyTaskPageObject applyTaskPageObject) {
        return UniflowConverter.INSTANCE.transformTasksToPager(applyTaskPageObject);
    }

    /**
     * 将待阅任务分页结果转化成Pager格式.
     * @author YTG
     * @param readPageObject 待阅Pager对象.
     * @return Pager<ReadObjectPojo> 任务分页信息
     **/
    @Override
    public Pager<ReadObjectPojo> transformReadTasksToPager(final ReadPageObject readPageObject) {
        return UniflowConverter.INSTANCE.transformTasksToPager(readPageObject);
    }

    /**
     * 设置当前处理人.
     * @author YTG
     * @return net.zoneland.uniflow.client.UserInfo
     **/
    private UserInfo getLoginUserInfo() {
        final UserInfo userInfo = new UserInfo();
        final SysUser user = SecurityUtils.getLoginUser().getUser();
        if(null != user){
            userInfo.setUserId(user.getUserName());
            userInfo.setUserName(user.getNickName());
            userInfo.setDeptId(user.getDeptDN());
            userInfo.setDeptName(user.getDeptName());
            userInfo.setCompanyId(user.getCompanyDN());
            userInfo.setCompanyName(user.getCompanyName());
        }
        return userInfo;
    }

    /**
     * 当传入的用户信息为空时，默认当前登录人.
     * @author YTG
     * @param userInfo 用户信息.
     * @return UserInfo 用户信息
     **/
    private UserInfo getUserInfo(final UserInfo userInfo) {
        return ObjectUtils.isNotEmpty(userInfo) ? userInfo : getLoginUserInfo();
    }

    /**
     * 当传入下一环节处理人信息为空时，默认处理人.
     * @author YTG
     * @param nextHandlerList 下一环节处理人信息.
     * @param userInfo 默认处理人.
     * @return net.zoneland.uniflow.client.UserInfo[]
     **/
    private UserInfo[] getUserInfos(final List<UserInfo> nextHandlerList, final UserInfo userInfo) {
        return ObjectUtils.isNotEmpty(nextHandlerList) ?
            nextHandlerList.toArray(new UserInfo[0]) : new UserInfo[]{userInfo};
    }

    /**
     * 将list集合转数组（ucc接口需要数组类型）.
     * @author YTG
     * @param data 数据.
     * @param array 数组.
     * @return T[]
     **/
    private <T> T[] toArray(final List<T> data, T[] array) {
        return data.toArray(array);
    }
}
